//
//  NSDate+Convenience.m
//  golfMaster
//
//  Created by 宋鹏程 on 14/7/14.
//  Copyright (c) 2014 Master. All rights reserved.
//

#import "NSDate+Convenience.h"
#import "NSObject+Convenience.h"

@implementation NSDate(Convenience)

#pragma mark -
#pragma mark - Convenience Methods

+ (instancetype)dateWithServerGMT:(NSNumber *)GMTSince1970
{
    if([GMTSince1970 isNull]) return nil;
    return [NSDate dateWithTimeIntervalSince1970:[GMTSince1970 longLongValue]];
}

- (NSString *)sinceNowDescription
{
    static const NSInteger TEN_MINUTE_UNIT = 10 * 60;
    static const NSInteger SEMI_HOUR = TEN_MINUTE_UNIT * 3;
    static const NSInteger ONE_HOUR = SEMI_HOUR * 2;
    static const NSInteger ONE_DAY = ONE_HOUR * 24;
    static const NSInteger ONE_WEEK = 7 * ONE_DAY;
    static const NSInteger ONE_YEAR = 365 * ONE_DAY;

    NSString *timeString = nil;
    NSTimeInterval interval = [self timeIntervalSinceNow] * -1;
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    
//    "just"	 = 	"Just"	;
//    "minutes_ago"	 = 	"minutes ago"	;
//    "half_an_hour_ago"	 = 	"half an hour ago"	;
//    "hours_ago"	 = 	"hours ago"	;
//    "days_ago"	 = 	"days ago"	;
//    "YYYYMMdd" = "yyyy-MM-dd";
//    "MMdd" = "MM-dd";

    if (interval >= ONE_YEAR) {
        [dateFormatter setDateFormat:@"yyyy年MM月dd日"];
//        [dateFormatter setDateStyle:NSDateFormatterMediumStyle];
//        [dateFormatter setLocale:[NSLocale currentLocale]];

        timeString = [dateFormatter stringFromDate:self];
    } else if (interval >= ONE_WEEK) {
        [dateFormatter setDateFormat: @"MM月dd日"];
        timeString = [dateFormatter stringFromDate:self];
    } else if (interval >= ONE_DAY) {
        timeString = [NSString stringWithFormat:@"%d%@", (NSInteger)interval / ONE_DAY,@"天前"];
    } else if (interval >= ONE_HOUR) {
        timeString = [NSString stringWithFormat:@"%d%@", (NSInteger)(interval / ONE_HOUR), @"小时前"];
    } else if (interval >= SEMI_HOUR) {
        timeString = [NSString stringWithFormat:@"半小时前"];
    } else if (interval >= TEN_MINUTE_UNIT) {
        timeString = [NSString stringWithFormat:@"%d0%@", (NSInteger)interval / TEN_MINUTE_UNIT,@"分钟前"];
    } else {
        timeString = [NSString stringWithFormat: @"刚刚"];
    }
    return timeString;
}


#pragma mark -
#pragma mark - Getter Methods

- (NSInteger)year
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    NSDateComponents *components = [gregorian components:NSYearCalendarUnit fromDate:self];
    return [components year];
}

- (NSInteger)month
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    NSDateComponents *components = [gregorian components:NSMonthCalendarUnit fromDate:self];
    return [components month];
}

- (NSInteger)day
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    NSDateComponents *components = [gregorian components:NSDayCalendarUnit fromDate:self];
    return [components day];
}

- (NSInteger)hour
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    NSDateComponents *components = [gregorian components:NSHourCalendarUnit fromDate:self];
    return [components hour];
}

- (NSInteger)minute
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    NSDateComponents *components = [gregorian components:NSMinuteCalendarUnit fromDate:self];
    return [components minute];
}

- (NSInteger)second
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    NSDateComponents *components = [gregorian components:NSSecondCalendarUnit fromDate:self];
    return [components second];
}

- (NSInteger)week
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    NSDateComponents *components = [gregorian components:NSWeekCalendarUnit fromDate:self];
    return [components week];
}

- (NSInteger)weekday
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    NSDateComponents *components = [gregorian components:NSWeekdayCalendarUnit fromDate:self];
    return [components weekday];
}


#pragma mark -
#pragma mark - Setter Methods

- (instancetype)setYear:(NSInteger)year
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setYear:year - self.year];
    
    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}

- (instancetype)setMonth:(NSInteger)month
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setMonth:month - self.month];
    
    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}

- (instancetype)setDay:(NSInteger)day
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setDay:day - self.day];
    
    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}

- (instancetype)setHour:(NSInteger)hour
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setHour:hour - self.hour];
    
    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}

- (instancetype)setMinute:(NSInteger)minute
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setMinute:minute - self.minute];
    
    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}

- (instancetype)setSecond:(NSInteger)second
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setSecond:second - self.second];
    
    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}

- (instancetype)setWeek:(NSInteger)week
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setWeek:week - self.week];
    
    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}

- (instancetype)setWeekday:(NSInteger)weekday
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setWeekday:weekday - self.weekday];
    
    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}

- (instancetype)offsetYears:(NSInteger)years
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setYear:years];
    
    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}

- (instancetype)offsetMonths:(NSInteger)months
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setMonth:months];
    
    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}

- (instancetype)offsetDays:(NSInteger)days
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setDay:days];
    
    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}

- (instancetype)offsetHours:(NSInteger)hours
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setHour:hours];

    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}

- (instancetype)offsetMinutes:(NSInteger)minutes
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setMinute:minutes];

    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}

- (instancetype)offsetSeconds:(NSInteger)seconds
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setSecond:seconds];
    
    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}

- (instancetype)offsetWeek:(NSInteger)weeks
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setWeek:weeks];
    
    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}

- (instancetype)offsetWeekday:(NSInteger)weekdays
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2];
    
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setWeekday:weekdays];
    
    return [gregorian dateByAddingComponents:offsetComponents toDate:self options:NSCalendarWrapComponents];
}


#pragma mark - 
#pragma mark - Public Methods

- (NSString *)weekdayString
{
    NSArray *weekdays = @[@"星期日", @"星期一", @"星期二", @"星期三", @"星期四", @"星期五", @"星期六"];
    return weekdays[self.weekday - 1];
}

- (NSString *)weekdayShortString
{
    NSArray *weekShorts = @[@"周日", @"周一", @"周二", @"周三", @"周四", @"周五", @"周六"];
    return weekShorts[self.weekday - 1];
}

- (NSString *)stringWithFormatter:(NSString *)format
{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:format];
    return [formatter stringFromDate:self];
}

- (NSUInteger)firstWeekDayInMonth
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    [gregorian setFirstWeekday:2]; // monday is first day
    
    NSDateComponents *components = [gregorian components:NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit fromDate:self];
    [components setDay:1];
    NSDate *newDate = [gregorian dateFromComponents:components];
    
    return [gregorian ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:newDate];
}

- (NSUInteger)numDaysInMonth
{
    NSCalendar *gregorian = [NSCalendar currentCalendar];
    
    NSRange range = [gregorian rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:self];
    return range.length;
}

@end
